package es.efor.ics.gev.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import es.efor.ics.gev.model.ValorEstadoFase.Id;

/**
 * Estado de una accion de una fase en un evento
 * 
 * @see Evento
 * @see Fase
 * @see Accion
 * @see EstadoFase
 * 
 * @author dlisbona
 *
 */
@Entity
@Table(name = "VAL_ESTADOS_ACCIONES")
public class ValorEstadoAccion extends BaseObject implements Serializable {

	/**
	 * Embedded composite identifier class that represents the primary key
	 * columns of the many-to-many join table.
	 */
	@Embeddable
	public static class Id implements Serializable {		
		private static final long serialVersionUID = 1281803991304667667L;
		
		private Long eventoId;
		private Long faseId;	
		private Long accionId;
		
		public Id() {			
		}

		public Id(Long eventoId, Long faseId, Long accionId) {		
			this.eventoId = eventoId;
			this.faseId = faseId;
			this.accionId = accionId;
		}
		
		@Column(name = "EVENTO_ID")
		public Long getEventoId() {
			return eventoId;
		}

		public void setEventoId(Long eventoId) {
			this.eventoId = eventoId;
		}

		@Column(name = "FASE_ID")
		public Long getFaseId() {
			return faseId;
		}
		
		public void setFaseId(Long faseId) {
			this.faseId = faseId;
		}

		@Column(name = "ACCION_ID")
		public Long getAccionId() {
			return accionId;
		}

		public void setAccionId(Long accionId) {
			this.accionId = accionId;
		}
		
		@Override
		public boolean equals(Object o) {
			if (o instanceof Id) {
				Id that = (Id) o;
				return this.getEventoId().equals(that.getEventoId())
						&& this.getFaseId().equals(that.getFaseId())
						&& this.getAccionId().equals(that.getAccionId());
			} else {
				return false;
			}
		}
		
		@Override
		public int hashCode() {			
			return getEventoId().hashCode() + getFaseId().hashCode() + getAccionId().hashCode();
		}
		
	}
	
	// static data
	private static final long serialVersionUID = -2728727060091313080L;

	// private instance data
	private Id id;
	private Evento evento;
	private Fase fase;
	private Accion accion;
	private EstadoAccion estadoAccion;
		
	/**
	 * Construct an uninitialized <code>ValorEstadoAccion</code>.
	 */
	protected ValorEstadoAccion() {		
	}
			
	/**
	 * Construct an initialized <code>ValorEstadoAccion</code>.
	 * 
	 * @param evento
	 * @param fase
	 * @param accion
	 * @param estadoAccion
	 */
	public ValorEstadoAccion(Evento evento, Fase fase, Accion accion,
			EstadoAccion estadoAccion) {		
		this.evento = evento;
		this.fase = fase;
		this.accion = accion;
		this.estadoAccion = estadoAccion;
		
		// Set primary key
		this.id = new Id(evento.getId(), fase.getId(), accion.getId());
	}

	@EmbeddedId
	public Id getId() {
		return id;
	}

	public void setId(Id id) {
		this.id = id;
	}
	
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "EVENTO_ID", insertable = false, updatable = false)
	@org.hibernate.annotations.ForeignKey(name = "FK_VAL_EST_ACCION_EVENTO_ID")
	public Evento getEvento() {
		return evento;
	}
	
	public void setEvento(Evento evento) {
		this.evento = evento;
	}
	
	@ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "FASE_ID", insertable = false, updatable = false)
    @org.hibernate.annotations.ForeignKey(name = "FK_VAL_EST_ACCION_FASE_ID")	
	public Fase getFase() {
		return fase;
	}

	public void setFase(Fase fase) {
		this.fase = fase;
	}
	
	@ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "ACCION_ID", insertable = false, updatable = false)
    @org.hibernate.annotations.ForeignKey(name = "FK_VAL_EST_ACCION_ACCION_ID")
	public Accion getAccion() {
		return accion;
	}

	public void setAccion(Accion accion) {
		this.accion = accion;
	}

	@Enumerated
    @Column(name = "ESTADO_ACCION", nullable=false)
	public EstadoAccion getEstadoAccion() {
		return estadoAccion;
	}

	public void setEstadoAccion(EstadoAccion estadoAccion) {
		this.estadoAccion = estadoAccion;
	}
	
	// ********************** Common Methods ********************** //

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null || getClass() != obj.getClass()) {
			return false;
		}		
		ValorEstadoAccion rhs = (ValorEstadoAccion) obj;
		return id.equals(rhs.id);
	}

	@Override
	public int hashCode() {		
		return id.hashCode();
	}

	@Override
	public String toString() {
		return new ToStringBuilder(this, ToStringStyle.DEFAULT_STYLE).
		append("evento", this.getEvento().getNombreEvento()).
		append("fase", this.getFase().getNombreFase()).
		append("accion", this.getAccion().getNombreAccion()).
		append("estado", this.getEstadoAccion().getValue()).		
		toString();
	}

}
